#!/usr/bin/env python

import argparse
import logging
import os
import sys
import time

import config

# Import from parent directory
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
try:
    import hmark.parseutility as parser
except ImportError:
    import tools.parseutility as parser


def main():
    originalDir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  # vuddy root directory
    abs_dir = os.path.join(originalDir, "abs")

    arg_parser = argparse.ArgumentParser()
    arg_parser.add_argument('REPO',
                            help='''Repository name''')
    arg_parser.add_argument('-a', '--abstract-level', required=True, type=int, nargs=1, choices=[0, 1, 2, 3, 4, 5],
                            help='''Abstract Level''')

    args = arg_parser.parse_args()

    projName = args.REPO
    intendedAbsLvl = 5
    if args.abstract_level:
        intendedAbsLvl = args.abstract_level[0]

    projDictList = []
    hashFileMapList = []

    for i in range(0, 6):
        projDictList.append({})
        hashFileMapList.append({})

    logging.info("loading all abstract func features.")
    feature_files = parser.load_abs_feature_files(os.path.join(abs_dir, projName))
    logging.info("(done)")

    time0 = time.time()

    numFiles = len(feature_files)
    numFuncs = 0
    numLines = 0

    deserializer = parser.FuncFeatures.get_deserializer()
    for file in feature_files:
        with open(file, 'r', encoding=config.ENCODING) as f:
            features_content = f.read().strip()
        features: parser.FuncFeatures = deserializer.deserialize(features_content)
        func_body = features.get_feature('abs_func_body')
        func_len = len(func_body)
        feature_hash = features.get_feature('abs_func_body_hash')
        func_id = features.get_feature('func_id')
        original_path = file.rstrip('.features')
        try:
            projDictList[intendedAbsLvl][func_len].append(feature_hash)
        except KeyError:
            projDictList[intendedAbsLvl][func_len] = [feature_hash]

        try:
            hashFileMapList[intendedAbsLvl][feature_hash].extend([original_path, func_id])
        except KeyError:
            hashFileMapList[intendedAbsLvl][feature_hash] = [original_path, func_id]

    packageInfo = config.VERSION + ' ' + str(projName) + ' ' + str(numFiles) + ' ' + str(numFuncs) + ' ' + str(
        numLines) + '\n'
    hidxDir = os.path.join(originalDir, "hidx")
    if os.path.exists(hidxDir) is False:
        os.makedirs(hidxDir)
    hidxFile = os.path.join(hidxDir, "hashmark_{0}_{1}.hidx".format(intendedAbsLvl, projName))
    with open(hidxFile, 'w') as fp:
        fp.write(packageInfo)
        for key in sorted(projDictList[intendedAbsLvl]):
            fp.write(str(key) + '\t')
            for h in list(set(projDictList[intendedAbsLvl][key])):
                fp.write(h + '\t')
            fp.write('\n')

        fp.write('\n=====\n')

        for key in sorted(hashFileMapList[intendedAbsLvl]):
            fp.write(str(key) + '\t')
            for f in hashFileMapList[intendedAbsLvl][key]:
                fp.write(str(f) + '\t')
            fp.write('\n')

    logging.info("Hash index saved to: %s",
                 os.path.join(originalDir, "hidx", "hashmark_{0}_{1}.hidx".format(intendedAbsLvl, projName)))
    time1 = time.time()
    logging.info("Elapsed time: %ss", time1 - time0)


if __name__ == "__main__":
    config.conf_log()
    main()
